package team.hyznrj.studentsys.configuration;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.shiro.authc.pam.AllSuccessfulStrategy;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import net.sf.ehcache.CacheManager;
import team.hyznrj.studentsys.dao.mapper.UrlPermissionMapper;
import team.hyznrj.studentsys.entity.UrlPermission;
import team.hyznrj.studentsys.security.LoginRealm;
@Configuration
@ComponentScan({"team.hyznrj.studentsys.service"})
public class ShiroConfiguration {
	/**
	 * 
	 * @return
	 */
	@Bean
	public LoginRealm createLoginRealm() {
		LoginRealm loginRealm = new LoginRealm();
//		//认证缓存开启
//		loginRealm.setAuthenticationCachingEnabled(true);
//		//这里sampleCache1可自定义，在ehcache里设置
//		loginRealm.setAuthenticationCacheName("sampleCache1");
		return loginRealm;
	}
	/**
	 * 权限/缓存管理开启
	 * @Title: securityManager
	 * @Description: 注入自定义的realm
	 * @Description: 
	 * 注意方法返回值SecurityManager为org.apache.shiro.mgt.SecurityManager
	 * 不要导错包
	 * @return
	 */
	/*
	 * <bean id="securityManager"
	 * class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property
	 * name="cacheManager" ref="cacheManager" /> <property name="authenticator"
	 * ref="authenticator"/> <property name="realms"> <list> <ref
	 * bean="jdbcRealm"/> <ref bean="jdbcRealm2"/> </list> </property> <!--
	 * Single realm app. If you have multiple realms, use the 'realms' property
	 * instead. --> <!-- <property name="realm" ref="jdbcRealm" /> --> </bean>
	 */
	@Bean
	public SecurityManager securityManager(EhCacheManager ehCacheManager ) {
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		//缓存需放在首位
		securityManager.setCacheManager(ehCacheManager);
		securityManager.setRealm(createLoginRealm());
		return securityManager;
	}
	/**
	 * 拦截器
	 * shiroFilter  
	 * @param securityManager
	 * @return
	 * @return ShiroFilterFactoryBean
	 */
	@Bean
	//TODO   
	public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager,UrlPermissionMapper mapper) {
//		System.out.println("ShiroConfiguration.shirFilter()");
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

		// 必须设置 SecurityManager
		shiroFilterFactoryBean.setSecurityManager(securityManager);

		// 拦截器.
		Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
		// 配置退出过滤器,其中的具体的退出代码Shiro已经替我们实现了
		filterChainDefinitionMap.put("/logout", "logout");
		// <!-- 过滤链定义，从上向下顺序执行，一般将 /**放在最为下边 -->
		// authc:所有url都必须认证通过才可以访问
		// anon:所有url都都可以匿名访问
		// js代码是可以直接被访问的
		filterChainDefinitionMap.put("/static/**", "anon");
		filterChainDefinitionMap.put("/account/login", "anon");
		filterChainDefinitionMap.put("/account/logout", "anon");
		filterChainDefinitionMap.put("/account/register", "anon");
		List<UrlPermission> selectByExample =mapper.selectByExample(null);
		// urlService.findAll();
		for(UrlPermission up:selectByExample){
			filterChainDefinitionMap.put(up.getUrl(), up.getPermissionNeeded());
		}
		shiroFilterFactoryBean.setLoginUrl("/Login/login.html");
		// 登录成功后要跳转的链接
		shiroFilterFactoryBean.setSuccessUrl("/Login/main.html");
		// 未授权界面;
		shiroFilterFactoryBean.setUnauthorizedUrl("/Login/unauthentication.html");
		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
		return shiroFilterFactoryBean;
	}
	/**
	 * 缓存管理
	 * cacheManager  
	 * @return
	 * @return EhCacheManager
	 */
	@Bean
	public EhCacheManager ehCacheManager(CacheManager cacheManager) {
		EhCacheManager e = new EhCacheManager();
		e.setCacheManager(cacheManager);
//		e.setCacheManagerConfigFile("src/main/resources/ehcache.xml");
		Cache<Object, Object> cache = e.getCache("sampleCache1");
		System.out.println(cache);
		return e;
	}

	/*
	 * 
	 * <bean id="authenticator"
	 * class="org.apache.shiro.authc.pam.ModularRealmAuthenticator"> <property
	 * name="authenticationStrategy"> <bean
	 * class="org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy"></bean>
	 * </property> </bean>
	 */
	@Bean
	public ModularRealmAuthenticator modularRealmAuthenticator() {
		ModularRealmAuthenticator m = new ModularRealmAuthenticator();
		m.setAuthenticationStrategy(new AllSuccessfulStrategy());
		return m;
	}

	@Bean
	LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
		return new LifecycleBeanPostProcessor();
	}
	 /**
	 * 开启shiro aop注解支持.
	 * 使用代理方式;所以需要开启代码支持;
	 * @param securityManager
	 * @return
	 */
	 @Bean
	 public AuthorizationAttributeSourceAdvisor
	 authorizationAttributeSourceAdvisor(SecurityManager securityManager){
	 AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor =
	 new AuthorizationAttributeSourceAdvisor();
	 authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
	 return authorizationAttributeSourceAdvisor;
	 }
	 @Bean
	 public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
		 return new DefaultAdvisorAutoProxyCreator();
	 }
}
